package com.gitee.huanminabc.utils_tools.security.controller;

import com.gitee.huanminabc.jcommon.str.StringIdentifyUtil;
import com.gitee.huanminabc.nullchain.common.NullResult;
import com.gitee.huanminabc.utils_tools.security.aspect.Anonymous;
import com.gitee.huanminabc.utils_tools.security.core.ContextHolder;
import com.gitee.huanminabc.utils_tools.security.entity.UserEntity;
import com.gitee.huanminabc.utils_tools.security.param.LoginParam;
import com.gitee.huanminabc.utils_tools.security.param.UserRegisterParam;
import com.gitee.huanminabc.utils_tools.security.param.UserUpdateParam;
import com.gitee.huanminabc.utils_tools.security.service.LoginService;
import com.gitee.huanminabc.utils_tools.security.service.UserService;
import com.gitee.huanminabc.utils_tools.security.vo.LoginUserVo;
import com.gitee.huanminabc.utils_tools.security.vo.TokenInfoVo;
import com.gitee.huanminabc.utils_tools.security.vo.UserPersonVo;
import com.gitee.huanminabc.utils_tools.web_base.utils.WebContextUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author huanmin
 */
@Api(tags = "UserController")
@RestController
@RequestMapping("/user")
@CrossOrigin
@Slf4j
public class UserSecurityController {

    @Autowired
    private UserService userService;
    @Autowired
    private LoginService loginService;





    /**
     * 登录
     */
    @PostMapping("/login")
    @ApiOperation("登录")
    public NullResult<TokenInfoVo> login(@RequestBody LoginParam loginParam) throws Exception {
        //如果account输入的是手机号,并且都是正数,则认为是手机号登录
        if (loginParam.getAccount().length() == 11&& StringIdentifyUtil.isPositiveNumeric(loginParam.getAccount())) {
            UserEntity byPhone = userService.findByPhone(loginParam.getAccount());
            if (byPhone != null) {
                loginParam.setAccount(byPhone.getAccount());
            }
            //如果通过手机号找不到用户,则认为是账户登录,那么就不做处理
        }

        TokenInfoVo login = loginService.login(loginParam);
        TokenInfoVo tokenInfoVo = new TokenInfoVo();
        BeanUtils.copyProperties(login, tokenInfoVo);
        return NullResult.success(tokenInfoVo);
    }

    /**
     * 退出登录
     */
    @DeleteMapping("/logout")
    @ApiOperation("退出登录")
    public NullResult<Boolean> logout() {
        boolean logout = loginService.logout(ContextHolder.CurrentUser().getUsername());
        ContextHolder.clearCurrentUser();
        return NullResult.success(logout);
    }

    //注册
    @PostMapping("/register")
    @ApiOperation("注册")
    public NullResult<Boolean> register(@RequestBody UserRegisterParam userRegisterParam) {
        return NullResult.success(userService.register(userRegisterParam));
    }

    //修改用户信息
    @PutMapping("/updateUser")
    @ApiOperation("修改用户信息")
    public NullResult<Boolean> updateUser(@RequestBody UserUpdateParam userUpdateParam) {
        return NullResult.success(userService.updateUser(userUpdateParam));
    }



    //拿旧refreshToken换新token
    @PostMapping("/refreshToken")
    @ApiOperation("刷新token")
    public NullResult<String> refreshToken() throws Exception {
        HttpServletRequest request = WebContextUtil.getRequest();
        String refreshToken = request.getHeader("refreshToken");
        log.info("refreshToken:{}",refreshToken);
        if (Strings.isBlank(refreshToken)) {
            return NullResult.error("refreshToken不能为空");
        }
        return NullResult.success(loginService.refreshToken(refreshToken));
    }

    @GetMapping("/currentUserInfoOpen")
    @ApiOperation("获取当前用户信息-用accessToken获取")
    @Anonymous
    public NullResult<LoginUserVo> currentUserInfoOpen(@RequestParam("accessToken") String accessToken){
        if (Strings.isBlank(accessToken)) {
            return NullResult.error("accessToken不能为空");
        }
        LoginUserVo tokenToUser = loginService.getTokenToUser(accessToken);
        LoginUserVo loginUserVo = new LoginUserVo();
        BeanUtils.copyProperties(tokenToUser, loginUserVo);
        return NullResult.success(loginUserVo );
    }


    @PostMapping("/currentUserInfo")
    @ApiOperation("获取当前用户信息")
    public NullResult<LoginUserVo> currentUserInfo()  {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof LoginUserVo) {
            LoginUserVo loginUserDto = (LoginUserVo) principal;
            loginUserDto.setAuthorities(null);
            loginUserDto.getSysUser().setPassword(null);

            LoginUserVo loginUserVo = new LoginUserVo();
            BeanUtils.copyProperties(loginUserDto, loginUserVo);

            return NullResult.success(loginUserVo);
        }
        return NullResult.error("获取用户信息失败");
    }

    @GetMapping("/getPersonUserInfo")
    @ApiOperation("获取当前用户信息")
    public NullResult<UserPersonVo> getPersonUserInfo(@RequestParam("account") String account) {
        UserPersonVo person = userService.getPerson(account);
        if (person == null) {
            return NullResult.error("用户不存在");
        }
        return NullResult.success(person);
    }

    //测试
    @GetMapping("/test")
    @ApiOperation("测试登录")
    public NullResult<Boolean> test() {
        return NullResult.success(true);
    }

    //通过传递userName来生成可使用的token,一般用于测试,和第三方接口对接
    @PostMapping("/createMockToken")
    @ApiOperation("通过传递userName来生成可使用的token,一般用于测试,和第三方接口对接")
    public NullResult<String> createMockToken(@RequestParam("account") String account,HttpServletRequest request) throws Exception {
        String appId = request.getHeader("appId");
        String appSecret = request.getHeader("appSecret");
        if (Strings.isBlank(appId) || Strings.isBlank(appSecret)) {
            return NullResult.error("appId或appSecret不能为空");
        }
        return NullResult.success(loginService.createMockToken(account,appId,appSecret));
    }


}
